home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’87 / Source ƒ.sit / Source ƒ / C ƒ / CITADEL BBS 'C' SRC / LOG.C < prev    next >
C/C++ Source or Header  |  1987-01-14  |  16KB  |  517 lines

  1. /************************************************************************/
  2. /*                log.c                    */
  3. /*                                    */
  4. /*       userlog code for  Citadel bulletin board system        */
  5. /************************************************************************/
  6.  
  7. /************************************************************************/
  8. /*                history                 */
  9. /*                                    */
  10. /* 85Nov15 HAW    MS-DOS library implemented.                */
  11. /* 85Aug31 HAW    Fix <.ep> problem.                    */
  12. /* 85Aug17 HAW    Update to onLine().                    */
  13. /* 85Aug10 HAW    Fix so system doesn't go out to disk on short pwds.    */
  14. /* 85Jul26 HAW    Kill noteLog(), insert anti-hack code in newPW().    */
  15. /* 85Jun13 HAW    Tweak code for networking stuff.            */
  16. /* 85Mar13 HAW    Moved zapLogFile() and logInit and logSort into confg.c.*/
  17. /* 85Jan19 HAW    Fix terminate() so room prompt isn't tossed at modem.    */
  18. /* 85Jan19 HAW    New Users are now directed to type ".help POLICY".    */
  19. /* 85Jan19 HAW    Move findPerson() into file.                */
  20. /* 84Dec15 HAW    Fix bug that allowed discovery of private rooms.    */
  21. /* 84Aug30 HAW    Now we roll into the 16-bit world.            */
  22. /* 84Jun23 HAW&JLS  Eliminating unused local variables using CRF.    */
  23. /* 84Jun19 JLS    Fixed terminate so that Mail> doesn't screw up SYSOP.    */
  24. /* 84Apr04 HAW    Started upgrade to BDS C 1.50a.             */
  25. /* 83Feb27 CrT    Fixed login-in-Mail> bug.                */
  26. /* 83Feb26 CrT    Limited # new messages for new users.            */
  27. /* 83Feb18 CrT    Null pw problem fixed.                    */
  28. /* 82Dec06 CrT    2.00 release.                        */
  29. /* 82Nov03 CrT    Began local history file & general V1.2 cleanup     */
  30. /************************************************************************/
  31.  
  32. #include "ctdl.h"
  33.  
  34. /************************************************************************/
  35. /*                contents                */
  36. /*                                    */
  37. /*    findPerson()        load log record for named person    */
  38. /*    hash()            hashes a string to an integer        */
  39. /*    login()         is menu-level routine to log caller in    */
  40. /*    newPW()         is menu-level routine to change a PW    */
  41. /*    newUser()        menu-level routine to log a new caller    */
  42. /*    PWSlot()        returns CTDLLOG.buf slot password is in */
  43. /*    slideLTab()        support routine for sorting logTab    */
  44. /*    storeLog()        store data in log            */
  45. /*    strCmpU()        strcmp(), but ignoring case distinctions*/
  46. /*    terminate()        menu-level routine to exit system    */
  47. /************************************************************************/
  48.  
  49. /************************************************************************/
  50. /*          External variable declarations in LOG.C        */
  51. /************************************************************************/
  52. int         thisSlot;        /* logTab slot logBuf found via */
  53. char         loggedIn = FALSE;    /* Global have-caller flag    */
  54. char         prevChar;        /* for EOLN/EOParagraph stuff    */
  55. char         expert;        /* true to suppress hints etc.    */
  56. char         termUpper;        /* uppercase only flag        */
  57. char         termLF;        /* LF-after-CR flag        */
  58. char         aide;            /* aide privileges flag     */
  59. char         sendTime;        /* send time msg created    */
  60. char         oldToo;        /* Send last old on new request?*/
  61. unsigned char     termWidth;        /* width to format output to    */
  62. unsigned char     termNulls;        /* # nulls to send at EOLN    */
  63. static char     pwChangeCount;     /* Anti-hack variable        */
  64.  
  65. /************************************************************************/
  66. /*          External variable definitions for LOG.C        */
  67. /************************************************************************/
  68. extern struct logBuffer logBuf;     /* Log buffer of a person    */
  69. extern struct lTable *logTab;        /* RAM index of pippuls     */
  70. extern struct config cfg;        /* Configuration variables    */
  71. extern struct rTable roomTab[];     /* RAM index of rooms        */
  72. extern struct aRoom  roomBuf;        /* Room buffer            */
  73. extern FILE         *logfl;        /* log file descriptor        */
  74. extern int         thisLog;        /* entry currently in logBuf    */
  75. extern char         outFlag;        /* Output skip flag        */
  76. extern char         whichIO;        /* Where IO's going...        */
  77. extern char         haveCarrier;    /* Do we still got carrier?    */
  78. extern char         echo;        /* Who gets what        */
  79. extern char         onConsole;     /* Where we get stuff from    */
  80. extern int         thisRoom;        /* The room we're in        */
  81. extern int         lastRoom;
  82. extern int         exitValue;
  83.  
  84. /************************************************************************/
  85. /*          External function definitions for LOG.C        */
  86. /************************************************************************/
  87. int  fread();
  88. char toUpper();
  89.  
  90. /************************************************************************/
  91. /*    findPerson() loads log record for named person.         */
  92. /*    RETURNS: ERROR if not found, else log record #            */
  93. /************************************************************************/
  94. int findPerson(name, lBuf)
  95. char            *name;
  96. struct logBuffer    *lBuf;
  97. {
  98.     int  h, i, foundIt, logNo;
  99.  
  100.     h    = hash(name);
  101.     for (foundIt = i = 0;  i < cfg.MAXLOGTAB && !foundIt;  i++) {
  102.     if (logTab[i].ltnmhash == h) {
  103.         getLog(lBuf, logNo = logTab[i].ltlogSlot);
  104.         if (strCmpU(name, lBuf->lbname) == SAMESTRING) {
  105.         foundIt = TRUE;
  106.         }
  107.     }
  108.     }
  109.     if (!foundIt)    return ERROR;
  110.     else         return logNo;
  111. }
  112.  
  113. /************************************************************************/
  114. /*    hash() hashes a string to an integer                */
  115. /************************************************************************/
  116. int hash(str)
  117. char *str;
  118. {
  119.     int  h, i, shift;
  120.  
  121.     for (h=shift=0;  *str;  shift=(shift+1)&7, str++) {
  122.     h ^= (i=toUpper(*str)) << shift;
  123.     }
  124.     return h;
  125. }
  126.  
  127. /************************************************************************/
  128. /*    login() is the menu-level routine to log someone in        */
  129. /************************************************************************/
  130. login(password)
  131. char *password;    /* TRUE if parameters follow    */
  132. {
  133.     char getYesNo();
  134.     int  foundIt, ltentry;
  135.  
  136.     foundIt =     ((ltentry = PWSlot(password, /*load = */TRUE)) != ERROR);
  137.     pwChangeCount = 1;
  138.  
  139.     if (foundIt && *password) {
  140.  
  141.     /* update userlog entries: */
  142.  
  143.     loggedIn     = TRUE;
  144.     setUp(TRUE);
  145.  
  146.     /* recite caller's name, etc:     */
  147.     mPrintf(" %s\n", logBuf.lbname);
  148.  
  149.     logMessage(L_IN, logBuf.lbname, FALSE);
  150.  
  151.     showMessages(NEWoNLY, FALSE);
  152.  
  153.      /* listRooms(!expert);  */
  154.     listRooms(expert ? NORNEW : LINNEW);
  155.     if (!expert)
  156.         listRooms(NOROLD);
  157.  
  158.     outFlag = OUTOK;
  159.     if (
  160.         (
  161.         logBuf.lbId[MAILSLOTS-1]
  162.         -
  163.         (logBuf.lbvisit[   logBuf.lbgen[MAILROOM] & CALLMASK   ]+1)
  164.         < 0x8000
  165.         )
  166.         &&
  167.         logBuf.lbId[MAILSLOTS-1] - cfg.oldest        < 0x8000
  168.         &&
  169.         thisRoom != MAILROOM
  170.     )   {
  171.         mPrintf("\n  * You have private mail in Mail> *\n ");
  172.     }
  173.  
  174.     } else {
  175.     /* discourage password-guessing: */
  176.     if (strLen(password) > 1 && whichIO == MODEM)
  177.         pause(2000);
  178.     if (!cfg.unlogLoginOk  &&  whichIO == MODEM)  {
  179.         mPrintf(" No record -- leave message to 'sysop' in Mail>\n ");
  180.     } else if (getYesNo(" No record: Enter as new user"))    newUser();
  181.     }
  182. }
  183.  
  184. /************************************************************************/
  185. /*    newPW() is menu-level routine to change one's password        */
  186. /*    since some Citadel nodes run in public locations, we avoid    */
  187. /*    displaying passwords on the console.                */
  188. /************************************************************************/
  189. newPW()
  190. {
  191.     char oldPw[NAMESIZE];
  192.     char pw[NAMESIZE];
  193.     int  goodPW;
  194.  
  195.     /* save password so we can find current user again: */
  196.     if (!loggedIn) {
  197.     mPrintf("\n How?\n ");
  198.     return ;
  199.     }
  200.     strcpy(oldPw, logBuf.lbpw);
  201.     storeLog();
  202.     do {
  203.     echo    = CALLER;
  204.     getNormStr(" new password", pw, NAMESIZE, NO_ECHO);
  205.     echo    = BOTH;
  206.  
  207.     /* check that PW isn't already claimed: */
  208.     goodPW = (PWSlot(pw,/* load = */TRUE) == ERROR    &&  strLen(pw) >= 2);
  209.  
  210.     if (pwChangeCount == 0) {
  211.         mPrintf("Hang on....\n");
  212.         pause(3000);            /* Discourage hacking    */
  213.     }
  214.     else pwChangeCount--;
  215.  
  216.     if (!goodPW) mPrintf("\n Poor password\n ");
  217.  
  218.     } while (!goodPW && (haveCarrier || whichIO==CONSOLE));
  219.  
  220.     doCR();
  221.     PWSlot(oldPw, /*load = */TRUE);    /* reload old log entry         */
  222.     pw[NAMESIZE-1] = 0x00;        /* insure against loss of carrier:*/
  223.  
  224.     if (goodPW    &&  strLen(pw) > 1) {    /* accept new PW:        */
  225.     strcpy(logBuf.lbpw, pw);
  226.     logTab[0].ltpwhash    = hash(pw);
  227.     storeLog();
  228.     }
  229.  
  230.     mPrintf("\n %s\n pw: ", logBuf.lbname);
  231.     echo = CALLER;
  232.     mPrintf("%s\n ", logBuf.lbpw);
  233.     echo = BOTH;
  234. }
  235.  
  236. /************************************************************************/
  237. /*    newUser() prompts for name and password             */
  238. /************************************************************************/
  239. newUser()
  240. {
  241.     char    getYesNo();
  242.     char    fullnm[NAMESIZE];
  243.     char    pw[NAMESIZE];
  244.     int     good, g, h, i, ok, ourSlot;
  245.     ulong    low;
  246.  
  247.     configure(FALSE);    /* make sure new users configure reasonably    */
  248.  
  249.     if (!expert)   tutorial("password.blb");
  250.  
  251.     do {
  252.     /* get name and check for uniqueness... */
  253.     do {
  254.         getNormStr(" Name", fullnm, NAMESIZE, ECHO);
  255.         h     = hash(fullnm);
  256.         for (i = 0, good = TRUE; i < cfg.MAXLOGTAB && good; i++) {
  257.         if (h == logTab[i].ltnmhash) good = FALSE;
  258.         }
  259.         if (
  260.         h == 0        /* "HUH?" --HAW 84Aug31         */
  261.         ||
  262.         h == hash("Citadel")
  263.         ||
  264.         h == hash("Sysop")
  265.         ) {
  266.         good = FALSE;
  267.         }
  268.         /* lie sometimes -- hash collision !=> name collision */
  269.         if (!good) mPrintf("We already have a %s\n", fullnm);
  270.     } while (!good    &&  (haveCarrier || whichIO==CONSOLE));
  271.  
  272.     /* get password and check for uniqueness...    */
  273.     do {
  274.         echo    = CALLER;
  275.         getNormStr(" password",  pw, NAMESIZE, ECHO);
  276.         echo    = BOTH    ;
  277.  
  278.         h     = hash(pw);
  279.         for (i = 0, good = strLen(pw) > 1;
  280.          i < cfg.MAXLOGTAB && good;
  281.          i++) {
  282.         if (h == logTab[i].ltpwhash) good = FALSE;
  283.         }
  284.         if (h == 0)   good = FALSE;
  285.         if (!good) {
  286.         mPrintf("\n Poor password\n ");
  287.         }
  288.     } while( !good    &&  (haveCarrier || whichIO==CONSOLE));
  289.  
  290.     mPrintf("\n nm: %s", fullnm);
  291.     mPrintf("\n pw: ");
  292.     echo = CALLER;
  293.     mPrintf("%s\n ", pw);
  294.     echo = BOTH;
  295.     } while (!getYesNo("OK") && (haveCarrier || whichIO==CONSOLE));
  296.  
  297.  
  298.     if (ok && (haveCarrier || whichIO == CONSOLE)) {
  299.  
  300.     logMessage(L_IN, fullnm, '+');
  301.  
  302.     /* kick least recent caller out of userlog and claim entry:    */
  303.     ourSlot         = logTab[cfg.MAXLOGTAB-1].ltlogSlot;
  304.  
  305.  
  306.     slideLTab(0, cfg.MAXLOGTAB-1);
  307.     logTab[0].ltlogSlot = ourSlot;
  308.     getLog(&logBuf, ourSlot);
  309.  
  310.     /* copy info into record:    */
  311.     strcpy(logBuf.lbname, fullnm);
  312.     strcpy(logBuf.lbpw, pw);
  313.     logBuf.lbflags.L_INUSE     = TRUE;
  314.     logBuf.lbflags.lflag1 =
  315.     logBuf.lbflags.lflag2 =
  316.     logBuf.lbflags.lflag3 =
  317.     logBuf.lbflags.lflag4 =
  318.     logBuf.lbflags.lflag5 =
  319.     logBuf.lbflags.lflag6 =
  320.     logBuf.lbflags.lflag7 =
  321.     logBuf.lbflags.lflag8 =
  322.     logBuf.lbflags.lflag9 = FALSE;
  323.     logBuf.lbflags.NET_PRIVS = FALSE;
  324.     logBuf.credit         = 0;        /* No L-D credit    */
  325.  
  326.     low = cfg.newest-50;
  327.     if (cfg.oldest - low < 0x8000)     low = cfg.oldest;
  328.     for (i=1;  i<MAXVISIT;    i++)   logBuf.lbvisit[i]= low;
  329.     logBuf.lbvisit[                   0]= cfg.newest;
  330.     logBuf.lbvisit[            (MAXVISIT-1)]= cfg.oldest;
  331.  
  332.     /* initialize rest of record:    */
  333.     for (i = 0;  i < MAXROOMS;  i++) {
  334.         if (roomTab[i].rtflags.PUBLIC == 1) {
  335.         g = (roomTab[i].rtgen);
  336.         logBuf.lbgen[i] = (g << GENSHIFT) + (MAXVISIT-1);
  337.         } else {
  338.         /* set to one less */
  339.         g = (roomTab[i].rtgen + (MAXGEN-1)) % MAXGEN;
  340.         logBuf.lbgen[i] = (g << GENSHIFT) + (MAXVISIT-1);
  341.         }
  342.     }
  343.     for (i = 0;  i < MAILSLOTS;  i++)  {
  344.         logBuf.lbslot[i]    = 0l;
  345.         logBuf.lbId[  i]    = cfg.oldest -1;
  346.     }
  347.  
  348.     /* fill in logTab entries    */
  349.     logTab[0].ltpwhash    = hash(pw)       ;
  350.     logTab[0].ltnmhash    = hash(fullnm)       ;
  351.     logTab[0].ltlogSlot    = thisLog       ;
  352.     logTab[0].ltnewest    = logBuf.lbvisit[0];
  353.  
  354.     /* special kludge for Mail> room, to signal no new mail:   */
  355.     roomTab[MAILROOM].rtlastMessage = logBuf.lbId[MAILSLOTS-1];
  356.  
  357.     loggedIn = TRUE;
  358.  
  359.     storeLog();
  360.  
  361.     /*    listRooms(!expert);   */
  362.     listRooms(expert ? NORNEW : LINNEW);
  363.     if (!expert)
  364.         listRooms(NOROLD);
  365.     mPrintf("\n \n Please type \".Help POLICY\"\n ");
  366.     }
  367. }
  368.  
  369. /************************************************************************/
  370. /*    PWSlot() returns userlog.buf slot password is in, else ERROR    */
  371. /*    NB: we also leave the record for the user in logBuf.        */
  372. /************************************************************************/
  373. int PWSlot(pw, load)
  374. char pw[NAMESIZE], load;
  375. {
  376.     int  h, i;
  377.     int  foundIt, ourSlot;
  378.     struct logBuffer lBuf;
  379.  
  380.     if (strLen(pw) < 2)     /* Don't search for these pwds        */
  381.     return ERROR;
  382.  
  383.     h = hash(pw);
  384.  
  385.     /* Check all passwords in memory: */
  386.     for(i = 0, foundIt = FALSE;  !foundIt && i < cfg.MAXLOGTAB;  i++) {
  387.     /* check for password match here */
  388.  
  389.     /* If password matches, check full password            */
  390.     /* with current newUser code, password hash collisions should    */
  391.     /* not be possible... but this is upward compatable & cheap    */
  392.     if (logTab[i].ltpwhash == h) {
  393.         ourSlot    = logTab[i].ltlogSlot;
  394.         getLog(&lBuf, ourSlot);
  395.  
  396.         if (strCmpU(pw, lBuf.lbpw) == SAMESTRING) {
  397.         /* found a complete match */
  398.         thisSlot = i   ;
  399.         foundIt  = TRUE;
  400.         }
  401.     }
  402.     }
  403.     if (foundIt) {
  404.     if (load == TRUE) {
  405.         movmem(&lBuf, &logBuf, sizeof logBuf);
  406.         thisLog = ourSlot;
  407.     }
  408.     return thisSlot;
  409.     }
  410.     else       return ERROR   ;
  411. }
  412.  
  413. /************************************************************************/
  414. /*    slideLTab() slides bottom N lots in logTab down.  For sorting.    */
  415. /************************************************************************/
  416. slideLTab(slot, last)
  417. int slot;
  418. int last;
  419. {
  420.     int i;
  421.  
  422.     /* open slot up: (movmem isn't guaranteed on overlaps) */
  423.     for (i = last - 1;    i >= slot;  i--)  {
  424.     movmem(&logTab[i], &logTab[i + 1], cfg.sizeLTentry);
  425.     }
  426. }
  427.  
  428. /************************************************************************/
  429. /*    storeLog() stores the current log record.            */
  430. /************************************************************************/
  431. storeLog()
  432. {
  433.     logTab[0].ltnewest      = cfg.newest;
  434.  
  435.     logBuf.lbvisit[0]      = cfg.newest;
  436.     logBuf.lbwidth      = termWidth;
  437.     logBuf.lbnulls      = termNulls;
  438.     logBuf.lbflags.EXPERT = (expert)    ? TRUE : FALSE;
  439.     logBuf.lbflags.UCMASK = (termUpper) ? TRUE : FALSE;
  440.     logBuf.lbflags.LFMASK = (termLF)    ? TRUE : FALSE;
  441.     logBuf.lbflags.AIDE   = (aide)    ? TRUE : FALSE;
  442.     logBuf.lbflags.TIME   = (sendTime)    ? TRUE : FALSE;
  443.     logBuf.lbflags.OLDTOO = (oldToo)    ? TRUE : FALSE;
  444.  
  445.     putLog(&logBuf, thisLog);
  446. }
  447.  
  448. /************************************************************************/
  449. /*    strCmpU() is strcmp(), but ignoring case distinctions        */
  450. /************************************************************************/
  451. int strCmpU(s, t)
  452. char s[], t[];
  453. {
  454.     int  i;
  455.  
  456.     i = 0;
  457.  
  458.     while (toUpper(s[i]) == toUpper(t[i])) {
  459.     if (s[i++] == '\0')  return 0;
  460.     }
  461.     return  toUpper(s[i]) - toUpper(t[i]);
  462. }
  463.  
  464. /************************************************************************/
  465. /*    terminate() is menu-level routine to exit system        */
  466. /************************************************************************/
  467. terminate(discon)
  468. char discon;
  469.     /* 1.  parameter <discon> is TRUE or FALSE.        */
  470.     /* 2.  if <discon> is TRUE, breaks modem connection    */
  471.     /*     or switches whichIO from CONSOLE to MODEM,    */
  472.     /*     as appropriate.                    */
  473.     /* 3.  modifies externs: struct logBuf,         */
  474.     /*             struct *logTab         */
  475.     /* 4.  returns no values                */
  476.     /*          modified    dvm 9-82            */
  477. {
  478.     int i;
  479.     char doStore;
  480.     int year, day, hours, minutes;
  481.     char *month;
  482.  
  483.     doStore = onLine();
  484.  
  485.     if (loggedIn)
  486.     mPrintf(" %s logged out\n ", logBuf.lbname);
  487.  
  488.     if (discon)  {
  489.     switch (whichIO) {
  490.     case MODEM:
  491.         interpret(cfg.pHangUp);
  492.         modIn();            /* And now detect carrier loss    */
  493.         break;
  494.     case CONSOLE:
  495.         whichIO =  MODEM;
  496.         printf("\n'MODEM' mode.\n ");
  497.         break;
  498.     }
  499.     getdate(&year, &month, &day, &hours, &minutes);
  500.     printf("%d%s%02d @ %d:%02d\n", year, month, day, hours, minutes);
  501.     }
  502.  
  503.     if (loggedIn) {
  504.  
  505.     logBuf.lbgen[thisRoom]    = roomBuf.rbgen << GENSHIFT;
  506.     if (doStore)   storeLog();
  507.     logMessage(L_OUT, "", (discon) ? 0 : '-');
  508.     loggedIn = FALSE;
  509.  
  510.     setUp(TRUE);
  511.     }
  512.  
  513.     for (i = 0; i < MAXROOMS; i++)    /* Clear skip bits */
  514.     roomTab[i].rtflags.SKIP = 0;
  515.     lastRoom = -1;
  516. }
  517.